package com.lyf.boot.config;

import com.lyf.boot.constant.RabbitMqConstant;
import org.springframework.amqp.core.*;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

import java.util.HashMap;
import java.util.Map;


/**
 * rabbit 3.6x 延迟队列，使用插件 rabbitmq-delayed-message-exchange
 * 插件下载地址： <a href="https://github.com/rabbitmq/rabbitmq-delayed-message-exchange/releases">插件</a>
 * 插件版本需要和rabbitmq一致，将下载的插件放到plugins目录中
 * @author Luyufan
 * @date 2023/7/10 16:49
 */
@Configuration
@ConditionalOnProperty(prefix = "spring.rabbitmq", name = "enabled", havingValue = "true")
public class RabbitMqConfig {


    /**
     * 延迟队列
     */
    @Bean
    public Queue delayQueue(){
        return new Queue(RabbitMqConstant.DELAY_QUEUE, true, false, false);
    }

    @Bean
    public CustomExchange delayExchange(){
        Map<String, Object> args = new HashMap<>(2);
        args.put("x-delayed-type", "direct");
        return new CustomExchange(RabbitMqConstant.DELAY_EXCHANGE, "x-delayed-message", true, false, args);
    }

    @Bean
    public Binding delayBinding(){
        return BindingBuilder.bind(delayQueue()).to(delayExchange()).with(RabbitMqConstant.DELAY_ROUTING).noargs();
    }

    /**
     rabbitTemplate.convertAndSend("delayedExchange", "delayRouting", "订单取消", message -> {
         message.getMessageProperties().setDelay(5000);
         return message;
     });
     **/

    /** 发布订阅 **/
    /** 广播 **/
    @Bean
    public Queue publishQueueOne(){
        return new Queue(RabbitMqConstant.PUBLISH_QUEUE_ONE, true, false, false);
    }

    @Bean
    public Queue publishQueueTwo(){
        return new Queue(RabbitMqConstant.PUBLISH_QUEUE_TWO, true, false, false);
    }

    @Bean
    public FanoutExchange fanoutExchange(){
        return new FanoutExchange(RabbitMqConstant.PUBLISH_FANOUT_EXCHANGE);
    }

    @Bean
    public Binding publishBindingOne() {
        return BindingBuilder.bind(publishQueueOne()).to(fanoutExchange());
    }

    @Bean
    public Binding publishBindingTwo() {
        return BindingBuilder.bind(publishQueueTwo()).to(fanoutExchange());
    }

    /** 一对一**/
    @Bean
    public Queue oneToOneQueue(){
        return new Queue(RabbitMqConstant.ONE_TO_ONE_QUEUE, true, false, false);
    }

    @Bean
    public Queue topicQueueA(){
        return new Queue(RabbitMqConstant.TOPIC_QUEUE_A,true, false, false);
    }

    @Bean
    public Queue topicQueueB(){
        return new Queue(RabbitMqConstant.TOPIC_QUEUE_B,true, false, false);
    }

    @Bean
    public TopicExchange topicExchange(){
        return new TopicExchange(RabbitMqConstant.TOPIC_EXCHANGE);
    }

    @Bean
    public Binding topicBindingA(){
        return BindingBuilder.bind(topicQueueA()).to(topicExchange()).with(RabbitMqConstant.TOPIC_ROUTING);
    }

    @Bean
    public Binding topicBindingB(){
        return BindingBuilder.bind(topicQueueB()).to(topicExchange()).with(RabbitMqConstant.TOPIC_ROUTING);
    }

}
